package top.simonby.iron.plugin.data.util;

import lombok.experimental.UtilityClass;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Bean工具
 *
 * @author 91223
 */
@UtilityClass
public class EntityBeanUtils {
    /**
     * 实体类转map
     *
     * @param obj
     * @return
     */
    public Map<String, Object> convertBeanToMap(Object obj) {
        return cn.hutool.core.bean.BeanUtil.beanToMap(obj);
    }


    public interface BaseGetProperties {
        /**
         * 排除满足的条件
         *
         * @param srcValue
         * @return
         */
        boolean fieldFunc(Object srcValue);
    }

    public void copyNullProperties(Object src, Object target) {
        BeanUtils.copyProperties(src, target, getCopyPropertyNames(src, srcValue -> srcValue == null));
    }

    public void copyEmptyStringProperties(Object src, Object target) {
        BeanUtils.copyProperties(src, target, getCopyPropertyNames(src, srcValue -> srcValue == null || "".equals(srcValue)));
    }

    /**
     * 获取不拷贝的数组集合
     *
     * @param source
     * @param baseGetProperties
     * @return
     */
    public String[] getCopyPropertyNames(Object source, BaseGetProperties baseGetProperties) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<String>();
        for (java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (baseGetProperties.fieldFunc(srcValue)) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    /***
     * 拷贝
     * @param src
     * @param target
     * @param baseGetProperties
     */
    public void copyProperties(Object src, Object target, BaseGetProperties baseGetProperties) {
        BeanUtils.copyProperties(src, target, getCopyPropertyNames(src, baseGetProperties));
    }

    /***
     * 拷贝
     * @param src
     * @param target
     */
    public void copyProperties(Object src, Object target, String... excludes) {
        BeanUtils.copyProperties(src, target, excludes);
    }


    /***
     * 拷贝
     * @param src
     * @param target
     * @param baseGetProperties
     */
    public void copyProperties(Object src, Object target, BaseGetProperties baseGetProperties, String... excludes) {
        String[] copyPropertyNames = getCopyPropertyNames(src, baseGetProperties);
        String[] concat = concat(copyPropertyNames, excludes);
        BeanUtils.copyProperties(src, target, concat);
    }

    /**
     * 合并数组
     *
     * @param first
     * @param second
     * @return
     */
    public String[] concat(String[] first, String[] second) {
        String[] result = Arrays.copyOf(first, first.length + second.length);
        System.arraycopy(second, 0, result, first.length, second.length);
        return result;
    }

}
